package cc.rengu.igas.opms.core.service.trans.quickpay;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.StageAmtInfo;
import cc.rengu.igas.opms.facade.request.StageAmtCalcRequest;
import cc.rengu.igas.opms.facade.response.StageAmtCalcResponse;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntStageInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 交易金额小于分期产品的最低交易限额时不可使用该分期产品
 *
 * @author keyi
 * @date 2020/3/24.
 */
public class StageAmtCalcService extends ManageService implements TransCustomImpl {
    @Override
    protected Object bizBeforeCust() throws Exception {
        StageAmtCalcRequest stageAmtCalcRequest = new StageAmtCalcRequest();
        ConvertUtil.convertOutput(stageAmtCalcRequest);
        return stageAmtCalcRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {

        BizResponse<StageAmtCalcResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        StageAmtCalcResponse stageAmtCalcResponse = new StageAmtCalcResponse();

        StageAmtCalcRequest stageAmtCalcRequest = (StageAmtCalcRequest) request;
        String instId = stageAmtCalcRequest.getHeader().getInstId();
        String mchntNo = stageAmtCalcRequest.getMchntNo();
        String stageProdCode = stageAmtCalcRequest.getStageProdCode();
        List<String> stageNumList = stageAmtCalcRequest.getStageNumList();

        //获取商户支持的分期产品信息
        MchntService mchntService = new MchntServiceImpl();
        List<MchntStageInfo> mchntStageInfoList = mchntService.getMchntStageInfo(instId, mchntNo);
        if (null == mchntStageInfoList || mchntStageInfoList.isEmpty()) {
            rglog.warn("当前商户<{}>暂未配置分期产品信息，不支持分期支付!");
            bizResponse.setRespCode(RespCodeEnum.MCHNT_NO_PROD.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.MCHNT_NO_PROD.getRespDesc());
            bizResponse.setResult(stageAmtCalcResponse);
            return bizResponse;
        }

        //获取商户支持有效的分期期数配置（在有效期类，且最低分期金额必须大于或等于上送的金额）
        String currentDate = DateUtil.getCurrentDate();
        mchntStageInfoList = mchntStageInfoList.stream().filter(item -> item.getProdStageCode().equals(stageProdCode) &&
                DateUtil.compareDate(currentDate, item.getFeeEffectiveDate()) >= OpmsParamConstant.INT_ZERO &&
                DateUtil.compareDate(currentDate, item.getFeeExpiryDate()) < OpmsParamConstant.INT_ZERO &&
                AmountUtil.compare(item.getStageLimitAmt(), stageAmtCalcRequest.getOrderAmt()) <= OpmsParamConstant.INT_ZERO).collect(Collectors.toList());

        //获取有效的需要进行分期试算的分期期数信息
        mchntStageInfoList = mchntStageInfoList.stream().filter(item -> stageNumList.contains(String.valueOf(item.getMchntStageNum()))).collect(Collectors.toList());
        List<String> stageNums = new ArrayList<>();
        mchntStageInfoList.forEach(item -> stageNums.add(String.valueOf(item.getMchntStageNum())));
        rglog.info("交易请求上送要进行分期试算的期数为：{}", JSON.toJSONString(stageNumList));
        rglog.info("需要进行分期试算的期数为：{}", JSON.toJSONString(stageNums));

        //调用通道进行分期金额试算
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(stageAmtCalcRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();

        for (MchntStageInfo mchntStageInfo : mchntStageInfoList) {
            GlobalTransUtil.setCacheValue(TransCacheConstant.MCHNT_STAGE_INFO, mchntStageInfo);
            channelBaseService.callService(txnInfo, null, channelCallCfg.getBizScene(), request);
            GlobalTransUtil.removeCacheValue(TransCacheConstant.MCHNT_STAGE_INFO);
        }

        //返回应答
        List<StageAmtInfo> stageAmtInfoList = (List<StageAmtInfo>) GlobalTransUtil.getCacheValue(TransCacheConstant.STAGE_AMT_INFO_LIST);
        stageAmtCalcResponse.setStageAmtInfo(stageAmtInfoList);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(stageAmtCalcResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        StageAmtCalcResponse stageAmtCalcResponse = (StageAmtCalcResponse) bizResponse.getResult();
        ConvertUtil.convertInput(stageAmtCalcResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item ->
                item.getBizScene().equals(ShareParamConstant.CALL_CFG_DEFAULT_BIZ_SCENE)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        List<StageAmtInfo> stageAmtInfoList = (List<StageAmtInfo>) GlobalTransUtil.getCacheValue(TransCacheConstant.STAGE_AMT_INFO_LIST);
        if (null == stageAmtInfoList) {
            stageAmtInfoList = new ArrayList<>();
        }
        //TODO 解析channelResponse结果，获取分期试算结果 ，并将分期试算结果放到交易全局缓存中
        //stageAmtInfoList.add(xxxx);
        GlobalTransUtil.setCacheValue(TransCacheConstant.STAGE_AMT_INFO_LIST, stageAmtInfoList);
        return transStatusEnum;
    }
}
